﻿using System;
using System.Linq;
using System.ServiceProcess;
using SuiHan.Commons.Logging;

namespace SuiHan.Commons.Daemon {
    /// <summary>
    /// Windows服务守护进程
    /// </summary>
    public class WindowsServiceDaemon : DaemonProcess {
        private readonly Logger logger;

        /// <summary>
        /// 服务名称
        /// </summary>
        public string ServiceName { get; }

        private ServiceController service;

        public WindowsServiceDaemon(string serviceName) {
            ServiceName = serviceName;
            logger = LoggerFactory.GetLogger($"{typeof(WindowsServiceDaemon).FullName}[{serviceName}]");
        }

        private ServiceController GetService() {
            try {
                ServiceController[] services = ServiceController.GetServices();
                ServiceController srv = services.FirstOrDefault(it => it.ServiceName == ServiceName);
                if (srv == null) {
                    logger.Error("服务不存在");
                }

                return srv;
            } catch (Exception e) {
                logger.Error($"查找服务异常: {e.Message}");
                return null;
            }
        }

        protected override void BeforeRun() {
            service = GetService();
        }

        protected override bool IsRunning() {
            ServiceControllerStatus? status = service?.Status;
            return status is not (ServiceControllerStatus.Paused or ServiceControllerStatus.Stopped);
        }

        protected override void RunProcess() {
            if (service != null) {
                logger.Debug("正在启动服务");
                try {
                    service.Start();
                    logger.Debug("服务启动成功");
                } catch (Exception e) {
                    logger.Error($"服务运行失败: {e.Message}");
                }
            } else {
                logger.Warn("服务不存在，运行失败");
            }
        }

        public override void KillProcess() {
            if (service == null) {
                BeforeRun();
            }

            if (service?.CanStop ?? false) {
                try {
                    service.Stop();
                } catch (Exception e) {
                    logger.Error("关闭服务异常: {0}", e.Message);
                }
            }
        }
    }
}
